package com.cheng.im.gateway.processer;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson2.JSONObject;
import com.cheng.im.common.constants.ProtoInstants;
import com.cheng.im.common.bean.Notification;
import com.cheng.im.common.bean.UserDTO;
import com.cheng.im.common.bean.msg.ProtoMsgV1;
import com.cheng.im.common.constants.MQConstants;
import com.cheng.im.common.entity.SessionCache;
import com.cheng.im.common.entity.UserCache;
import com.cheng.im.gateway.mq.RocketMQProduce;
import com.cheng.im.gateway.protobuilder.LoginResponseBuilder;
import com.cheng.im.gateway.protobuilder.NotificationMsgBuilder;
import com.cheng.im.gateway.session.LocalSession;
import com.cheng.im.gateway.session.dao.impl.RedissonUserCacheImpl;
import com.cheng.im.gateway.session.manager.SessionManger;
import com.cheng.im.service.common.resp.CommonResult;
import com.cheng.im.service.user.service.ImUserDataService;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Map;

/**
 * @author Cheng
 */
@Data
@Slf4j
@Service
public class LoginProcesser {
    @Resource
    LoginResponseBuilder loginResponseBuilder;
    @Resource
    private SessionManger sessionManger;
    @DubboReference
    ImUserDataService imUserDataService;
    @Resource
    private RedissonUserCacheImpl userCacheDAO;
    @Resource
    RocketMQProduce rocketMQProduce;

    public Boolean action(LocalSession session,
                          ProtoMsgV1.Message proto)
    {
        // 1.取出token验证
        ProtoMsgV1.LoginRequest info = proto.getLoginRequest();
        long seqNo = proto.getSequence();

        UserDTO user = UserDTO.fromMsg(info);
        user.setAppId(proto.getAppId());
        user.setSessionId(session.getSessionId());

        // 2.检查用户
        boolean isValidUser = checkUser(user);
        if (!isValidUser)
        {
            ProtoInstants.ResultCodeEnum resultcode = ProtoInstants.ResultCodeEnum.NO_TOKEN;
            ProtoMsgV1.Message response = loginResponseBuilder.loginResponse(resultcode, seqNo, "-1");
            //发送之后，断开连接
            session.writeAndClose(response);
            return false;
        }

        // 本地会话
        session.setUser(user);

        /**
         * 绑定session
         */
        session.bind();
        sessionManger.addLocalSession(session);



        // 解决多端登录问题
        UserCache userCache = userCacheDAO.get(user.getUserId(), proto.getAppId());

        if (!ObjectUtil.isNull(userCache)) {
            // map为空就结束
            Map<String, SessionCache> map = userCache.getMap();

            map.values().stream().forEach(sessionCache -> {
                if (sessionCache.getSessionId().equals(session.getSessionId())) return;

                if (sessionCache.getPlatformType().equals(info.getPlatformType())) {
                    log.info("同一个平台登录多台设备顶号通知 设备{}：下线", sessionCache.getSessionId());

//                ImNode node = ImWorker.getInst().getLocalNode();
//                if (sessionCache.getImNode().getHost().equals(node.getHost())
//                        && sessionCache.getImNode().getPort().equals(node.getPort())) {
//                    LocalSession sessionBySession = (LocalSession) sessionManger.getSessionBySession(sessionCache.getSessionId());
//
//                    sessionBySession.close();
//                    //删除本地的会话和远程会话
//                    sessionManger.removeSession(sessionCache.getSessionId(), userCache.getAppId());
//                }else {
//
//                }
                    // 顶号退出登录消息包 todo：消息类型不应该这个
                    Notification<UserDTO> notification = new Notification<>(user);
                    notification.setType(Notification.SESSION_OFF);
                    ProtoMsgV1.Message message = NotificationMsgBuilder
                            .buildNotification(JSONObject.toJSONString(notification), sessionCache.getSessionId(),
                                    userCache.getAppId());

                    // 消息发送
                    rocketMQProduce.sendMessage(MQConstants.IM_2_IM, message, sessionCache.getImNode().getBrokerId());
                }
            });
        }

        /**
         * 通知客户端：登录成功
         */
        ProtoInstants.ResultCodeEnum resultcode = ProtoInstants.ResultCodeEnum.SUCCESS;
        ProtoMsgV1.Message response =
                loginResponseBuilder.loginResponse(resultcode, seqNo, session.getSessionId());
        session.writeAndFlush(response);
        return true;
    }


    private boolean checkUser(UserDTO user)
    {
        CommonResult commonResult = imUserDataService.checkToken(user.getToken());
        if (commonResult.isOk()){
            return true;
        }
        return false;
    }


}
